-- UIElemAltar
-- Created by chengb May/7/2015
-- 元素圣坛

require "game/ui/form/equips/UIDiary";

UIElemAltar = class("UIElemAltar", function()
    return cc.Layer:create();
end);

-- 特殊元素圣坛类型
local LORDALTAR = {[1] = "earth_altar", [2] = "water_altar", [4] = "fire_altar", [8] = "thunder_altar"};

function UIElemAltar.create(pos)
    return UIElemAltar.new(pos);
end

-- 构造函数
function UIElemAltar:ctor(pos)
    self:setName("UIElemAltar");

    -- 初始化
    local node = cc.CSLoader:createNode("layout/altar/ElemAltar.csb");
    self:addChild(node);
    self.node = node;

    self:setLocalZOrder(UIMgr.TOP_MENU_ZORDER + 1);

    -- 记录元素圣坛的位置
    self.pos = pos;

    self.grid = DungeonM.getGridByPos(pos);

    -- 注册点击事件
    self:registerTouchEvent();

    -- 注册事件处理回调函数
    self:registerEventCallback();

    -- 重绘
    self:redraw();

    -- 适配
    self:resize();
end

-- 适配
function UIElemAltar:resize()
    local node = self.node;
    local w = AlignM.frameSize.width;
    local h = AlignM.frameSize.height;

    -- bg居中显示并充满整个屏幕
    AlignM.fitToScreen(node, "bg");

    -- CT居中并缩放至合适大小
    AlignM.alignToCenter(node, "CT");

    -- BT置于底部并缩放至合适大小
    AlignM.alignToBottomCenter(node, "BT");
end

-- 绘制已提交的水晶
function UIElemAltar:redrawExitedElems()
    -- 元素祭坛图标
    local iconImg = findChildByName(self.node, "CT/icon");
    iconImg:setScale(1.3);

    if self.grid.type == GRID_TYPE_ELEMENT_LORD or
        self.grid.type == GRID_TYPE_SPECIAL_ELEMENT_LORD then
        local icon = self.grid.icon;
        local iconPath = getLevelItemIconPath(icon);
        iconImg:loadTexture(iconPath);
    end

    -- 绘制已插入的水晶
    local leftNode = findChildByName(iconImg, "left_node");
    local rightNode = findChildByName(iconImg, "right_node");
    local midNode = findChildByName(iconImg, "mid_node");
    local iconNodeList = { { "left", leftNode }, { "right", rightNode }, { "mid", midNode }, };

    -- 获取已经提交的元素
    local existedElems;
    if self.grid.type == GRID_TYPE_SPECIAL_ELEMENT_LORD then
        existedElems = ElementAltarM.getSpecialSubmittedElems(self.pos);
    else
        existedElems = ElementAltarM.getSubmittedElems(self.pos);
    end
    printTable(existedElems, "已经提交的元素");

    local i = 0;
    for _, arr in pairs(iconNodeList) do
        local dir      = arr[1];
        local iconNode = arr[2];
        i = i + 1;
        local elem = existedElems[i];
        if not elem then
            iconNode:setVisible(false);
        else
            iconNode:setVisible(true);
            local index;
            if self.grid.type == GRID_TYPE_SPECIAL_ELEMENT_LORD then
                index = self.grid.elem_icon_index;
            else
                index = table.indexOf(ELEM_LIST,  elem);
            end

            if index < 0 then
                trace("UIElemAltar", "未知的元素:" .. elem);
            end
            local iconName = string.format("%s_elem%d", dir, index);
            local elemIconImg = findChildByName(iconNode, "icon");
            local initPosX = elemIconImg:getPositionX();
            local initPosY = elemIconImg:getPositionY();
            elemIconImg:loadTexture("images/ui/elem_altar/" .. iconName .. ".png");
            elemIconImg:setPosition(cc.p(initPosX, initPosY));
        end
    end
end

-- 重绘
local diaryId = 7058;
function UIElemAltar:redraw()
    -- 标题
    local titleLabel = findChildByName(self.node, "CT/title_node/title");

    local desc;
    if self.grid.type == GRID_TYPE_SPECIAL_ELEMENT_LORD then
        local typ = self.grid.altar_type;

        titleLabel:setString(getLocStr(LORDALTAR[typ]));
        desc = getLocStr("special_lord_altar_desc");
    elseif self.grid.type == GRID_TYPE_ELEMENT_LORD then
        local typ = self.grid.altar_type;

        titleLabel:setString(getLocStr(LORDALTAR[typ]));
        desc = getLocStr("lord_altar_desc");
    else
        titleLabel:setString(getLocStr("elem_altar"));
        desc = getLocStr("elem_altar_desc");
    end
    TextStyleM.setArtWordTitleStyle(titleLabel);

    -- 描述
    local descLabel  = findChildByName(self.node, "CT/desc");
    TextStyleM.setTextStyle(descLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_DARK_BROWN);
    applyString(descLabel, desc);

    -- 绘制已提交的水晶
    self:redrawExitedElems();

    -- 绘制各元素结晶图标和数量
    local elemNode = findChildByName(self.node, "CT/elem_node");
    local CT = findChildByName(self.node, "CT");
    for i, elem in pairs(ELEM_LIST) do
        local child = findChildByName(elemNode, "item" .. i);
        local iconImg = findChildByName(child, "icon");
        local amountLabel = findChildByName(child, "amount");

        local require;
        local classId;

        if self.grid.type == GRID_TYPE_SPECIAL_ELEMENT_LORD then
            classId = self.grid.require[i];
        else
            require = ElementAltarM.queryElement(elem, "require");
            classId = table.keys(require)[1];
        end

        -- 水晶图标
        local icon = ItemM.query(classId, "icon");
        iconImg:loadTexture(getItemIconPath(icon));
        iconImg:setScale(0.83);

        -- 水晶数量
        local amount = ItemM.getAmount(ME.user, classId);
        TextStyleM.setTextStyle(amountLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_BEIGE);
        amountLabel:setString(tostring(amount));

        -- 绘制提交按钮状态
        local btn = findChildByName(CT, "btn_elem" .. i);
        if amount <= 0 then
            -- 没有水晶，按钮置灰
            btn:setTouchEnabled(false);
            btn:setBright(false);
        else
            btn:setTouchEnabled(true);
            btn:setBright(true);
        end
    end

    -- 日记按钮
    local btnDiary = findChildByName(self.node, "BT/btn_diary");
    local propertyList = PropertyM.getUserProperties();

    -- 如果玩家包裹中没有日记，则不显示日记按钮
    if table.indexOf(propertyList, diaryId) ~= -1 then
        btnDiary:setVisible(true);
    else
        btnDiary:setVisible(false);
    end
end

-- 注册点击事件
function UIElemAltar:registerTouchEvent()
    -- 注册返回按钮点击事件
    local btnBack = findChildByName(self.node, "BT/btn_back");
    local function onBackClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_return");

            -- 关闭当前界面
            UIMgr.getCurrentScene():removeFormByName("UIElemAltar");
        end
    end
    AddBackEventHandler(self, btnBack, onBackClick);
    TextStyleM.setTextStyle(btnBack, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnBack:setTitleText(getLocStr("btn_text_back"));

    -- 注册日记按钮点击事件
    local btnDiary = findChildByName(self.node, "BT/btn_diary");
    local function onDiaryBtnClick(sender, eventType)
        if eventType == ccui.TouchEventType.ended then
            AudioM.playFx("button_click");

            -- 显示日记界面
            local uiDiary = UIDiary.create(diaryId);
            UIMgr.getCurrentScene():addForm(uiDiary);
        end
    end
    btnDiary:addTouchEventListener(onDiaryBtnClick);
    TextStyleM.setTextStyle(btnDiary, TextStyleM.TEXT_SIZE_MIDDLE, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true);
    btnDiary:setTitleText(getLocStr("btn_text_diary"));

    -- 注册各个元素按钮点击事件
    local CT = findChildByName(self.node, "CT");
    for i, elem in pairs(ELEM_LIST) do
        local btn = findChildByName(CT, "btn_elem" .. i);

        -- 显示按钮
        local cost = ElementAltarM.queryElement(elem, "require") or {};
        local classId = table.keys(cost)[1];
        local icon = ItemM.query(classId, "icon");

        local iconImg = findChildByName(btn, "icon");
        iconImg:loadTexture(getItemIconPath(icon));

        local descLabel = findChildByName(btn, "desc");
        local descTxt   = getLocStr("input_elem_item");
        TextStyleM.setTextStyle(descLabel, TextStyleM.TEXT_SIZE_SMALL, TextStyleM.TEXT_COLOR_BROWN_YELLOW, true, nil, nil, nil, nil, nil, true, TextStyleM.getTextScale(descTxt, 6 * 2));
        descLabel:setString(descTxt);

        -- 适当缩小文本间距
        descLabel:getVirtualRenderer():setAdditionalKerning(getLocKerning() -2);

        local function onClicked(sender, eventType)
            if eventType == ccui.TouchEventType.ended then
                AudioM.playFx("button_click");
                -- 尝试提交
                self:trySubmit(elem);
            end
        end
        btn:addTouchEventListener(onClicked);
    end
end

-- 注册事件处理回调函数
function UIElemAltar:registerEventCallback()
    -- 关注提交水晶的事件
    EventMgr.register("UIElemAltar", event.SUBMIT_ELEM, function(args)
        local elem    = args.elem;
        local id      = args.id;
        local isFinal = args.isFinal;
        local pos     = args.pos;
        local grid    = DungeonM.getGridByPos(pos);
        local class   = grid.class;

        -- 提示玩家
        local msg;
        if DungeonM.query(class, "rule") == "special_element_lord" then
            msg = getLocStr("submit_special_elem_item_succ");
        elseif not isFinal then
            -- 还未圆满，提示提交成功
            local name = ElementAltarM.queryElement(elem, "name");
            msg = string.format(getLocStr("submit_elem_item_succ"), name);
        else
            local tip = ElementAltarM.query(id, "activate_tip");
            if type(tip) == "string" and tip ~= "" then
                -- 如果配置了元素圣坛激活的提示，直接使用
                msg = tip;
            else
                msg = getLocStr("elem_altar_active");
            end
        end

        alert(msg);

        -- 关闭当前界面
        UIMgr.getCurrentScene():removeFormByName("UIElemAltar");
    end);

    -- 关注插入结晶失败事件
    EventMgr.register("UIElemAltar", event.ELEM_FAIL_SUBMIT, function(args)
        local elem    = args.elem;
        local pos     = args.pos;
        local grid    = DungeonM.getGridByPos(pos);
        local class   = grid.class;
cclog(G.."pos = %o\n"..W, pos);
        -- 提示玩家结晶粉碎
        local msg = getLocStr("smash_element");

cclog(G.."class = %o\n"..W, class);
cclog(G.."rule = %o\n"..W, DungeonM.query(class, "rule"));

        if DungeonM.query(class, "rule") == "special_element_lord" then
            msg = getLocStr("smash_special_element");
        end

        alert(msg);

        -- 关闭当前界面
        UIMgr.getCurrentScene():removeFormByName("UIElemAltar");
    end);

    -- 关注提交成功的事件
    EventMgr.register("UIElemAltar", event.SUBMIT_LORD_ELEM, function(args)
        local elem    = args.elem;
        local id      = args.id;
        local isFinal = args.isFinal;

        -- 提示玩家
        local msg;
        -- 提示提交成功
        local name = ElementAltarM.queryElement(elem, "name");
        msg = string.format(getLocStr("submit_elem_item_succ"), name);

        alert(msg);

        -- 关闭当前界面
        UIMgr.getCurrentScene():removeFormByName("UIElemAltar");
    end);


    self:registerScriptHandler(function(eventType)
        if eventType == "exit" then
            cclog("UIElemAltar 界面析构清理");

            EventMgr.removeAll("UIElemAltar");

            if UIDungeonMgr:getCurLevel() then
                UIDungeonMgr:getCurLevel():showMenu();
            end
        elseif eventType == "enter" then
            if UIDungeonMgr:getCurLevel() then
                UIDungeonMgr:getCurLevel():hideMenu();
            end
        end
    end);
end

-- 尝试提交
function UIElemAltar:trySubmit(elem)
    local grid = DungeonM.getGridByPos(self.pos);
    local cost;
    local classId;

    if grid.type == GRID_TYPE_SPECIAL_ELEMENT_LORD then
        local index = table.indexOf(ELEM_LIST, elem);
        classId = self.grid.require[index];
    else
        cost = ElementAltarM.queryElement(elem, "require") or {};
        classId = table.keys(cost)[1];
    end

    if ItemM.getAmount(ME.user, classId) <= 0 then
        -- 提示没有该水晶
        local name = ItemM.query(classId, "name");
        alert(string.format(getLocStr("lack_item_tip"), name));
        return false;
    end

    -- 提交
    -- 如果不是圣坛格子
    local ok;
    if  grid.type == GRID_TYPE_ELEMENT_ALTAR or grid.type == GRID_TYPE_SKY_ELE_ALTAR then
        ok = DungeonActionM.go("submit_element", self.pos, elem);
    elseif grid.type == GRID_TYPE_SPECIAL_ELEMENT_LORD then
        -- 提交特殊元素领主圣坛结晶
        ok = DungeonActionM.go("submit_special_lord_element", self.pos, classId);
    else
        -- 提交元素领主圣坛结晶
        ok = DungeonActionM.go("submit_lord_element", self.pos, elem);
    end

    if ok ~= true then
        return false;
    end

    return true;
end
